/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.chris.webservice.manager;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.chris.webservice.dao.LocationDao;
import com.chris.webservice.entity.QueryInfoLog;
import com.chris.webservice.manager.intf.ILocationManager;
import com.chris.webservice.utils.PropertiesUtil;
import com.chris.webservice.ws.common.OmcConstants;
import com.chris.webservice.ws.common.PosType;
import com.chris.webservice.ws.dto.Device;
import com.chris.webservice.ws.dto.Devices;
import com.chris.webservice.ws.dto.RequesterID;
import com.chris.webservice.ws.result.dto.CallerInfo;
import com.chris.webservice.ws.result.dto.PosInfo;
import com.chris.webservice.ws.result.dto.PosInfos;
import com.chris.webservice.ws.result.dto.Result;
import com.jasic.comnt.cache.RequestCache;
import com.jasic.comnt.cache.ResponseCache;
import com.jasic.comnt.cache.SocketCache;
import com.jasic.comnt.cache.bean.RequestTask;
import com.jasic.comnt.cache.bean.ResponseResult;
import com.jasic.comnt.protocol.bean.PostionReq;
import com.jasic.comnt.protocol.bean.PostionResp;

/**
 *
 * @author Chris
 */
@Stateless
public class LocationManager implements ILocationManager {

	@EJB
    private LocationDao locationDao;
	
	private SimpleDateFormat formatDate1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private SimpleDateFormat formatDate2 = new SimpleDateFormat("yyyyMMddHHmmss");
	
    protected static Logger logger = LoggerFactory
            .getLogger(LocationManager.class);

    public synchronized Result getLocation(RequesterID requesterID, Devices devices) {
    	String uuid = java.util.UUID.randomUUID().toString();
    	
    	Date start = new Date();
    	
    	if (requesterID == null || requesterID.getUsername() == null || requesterID.getPassword() == null) {
    		return null;
    	}
    	
    	//查询数据库，判断用户名密码是否正确
    	int id = locationDao.checkUser(requesterID.getUsername(), requesterID.getPassword());
		if (id == 0) {
			return null;
		}
    	
    	//先判断locationSocket是否允许并连接到服务器
    	if (!SocketCache.postSocketConnected()) {
    		return null;
    	}
    	
		Result result = new Result();
		CallerInfo callerInfo = new CallerInfo();
		callerInfo.setCallerId("weizhi");
		result.setCallerInfo(callerInfo);
		
		
		if (devices == null) {
			logger.info("devices == null");
			result.setReturnCode(0);
			return result;
		}
		//封装位置数据包放到socket队列
		this.putRequestCache(uuid, devices);
		
		
    	boolean b = true;
    	int count = 0;
    	String returnContent = "";
    	//获取延时时间
    	PropertiesUtil properties = PropertiesUtil.getInstance(OmcConstants.APPLICATION_PROPERTIES);
    	Integer socketTimeout = Integer.parseInt(properties.getValue("socketTimeout"));
    	
    	//等待locationSocket返回信息
    	while (b) {
    		try {
    			count++;
    			logger.info(count+"");
    			if (count > socketTimeout) {
    				//当socket相应超时
    				result.setReturnCode(1);
    				break;
    			}
    			
    			//获取返回缓存信息
    			if (ResponseCache.getPostResp(uuid) != null) {
    				ResponseResult<PostionResp> responseResult = ResponseCache.getPostResp(uuid);
    				result.setReturnCode(0);
    				result.setPosInfos(this.getPosInfos(responseResult.getRequests()));
    				returnContent = this.getReturnContent(responseResult.getRequests());
    				break;
    			}
    			
    			Thread.sleep(1000);
    		} catch (InterruptedException e) {
    			logger.error(e.getMessage());
    		}
    	}
    	
    	Date end = new Date();
    	//将客户请求记入到日志
    	QueryInfoLog queryInfoLog = new QueryInfoLog();
    	queryInfoLog.setRequestID(id);
    	queryInfoLog.setRequestTime(formatDate1.format(start));
    	queryInfoLog.setRequestContent(this.getRequestContent(requesterID, devices));
    	queryInfoLog.setReturnContent(returnContent);
    	queryInfoLog.setReturnCode(result.getReturnCode());
    	queryInfoLog.setReturnTime(formatDate1.format(end));
//    	queryInfoLog.setReturnID();
//    	locationDao.addLog(queryInfoLog);
    	

        return result;
    }
    
    private String getRequestContent(RequesterID requesterID, Devices devices) {
    	String result = "";
    	if (requesterID != null) {
    		result += "Username = " + requesterID.getUsername();
    		result += ", Password = " + requesterID.getPassword();
    	}
    	if (devices != null) {
    		for (Device device : devices.getDevice()) {
    			result += ", device: id = " + device.getID();
    			result += ", PosType = " + device.getPosType();
    		}
    	}
    	
    	return result;
    }
    
    private String getReturnContent(List<PostionResp> list) {
    	String result = "";
    	if (list != null) {			
			for (PostionResp postionResp : list) {
				String posType = PosType.getByValue(postionResp.getTarget_type()).getName();
				Date date = new Date();
				
				result += ", PositionResult = " + postionResp.getPositionResult();
				result += ", Id = " + postionResp.getTarget_id();
				result += ", posType = " + posType;
				result += ", LocalTime = " + formatDate2.format(date);
				result += ", Longitude = " + postionResp.getLongitude();
				result += ", Latitude = " + postionResp.getLatitude();
			}
			
			if (result.length() > 0) {
				result = result.substring(2);
			}	
		}
    	
    	return result;
    }
    
    private PosInfos getPosInfos(List<PostionResp> list) {
    	PosInfos posInfos = null;
    	if (list != null) {
			posInfos = new PosInfos();
			List<PosInfo> posInfoList = new ArrayList<PosInfo>();
			
			for (PostionResp postionResp : list) {
				PosInfo posInfo = new PosInfo();
				posInfo.setPositionResult(postionResp.getPositionResult());
				posInfo.setId(postionResp.getTarget_id());
				
				String posType = PosType.getByValue(postionResp.getTarget_type()).getName();
				posInfo.setPosType(posType);
				Date date = new Date();
				posInfo.setLocalTime(formatDate2.format(date));
				posInfo.setLongitude(postionResp.getLongitude() + "");
				posInfo.setLatitude(postionResp.getLatitude() + "");
				
				posInfoList.add(posInfo);
			}
			
			posInfos.setPosInfo(posInfoList);		
		}
    	
    	return posInfos;
    }
    
    private void putRequestCache (String uuid, Devices devices) {
    	RequestTask<PostionReq> rt = new RequestTask<PostionReq>();
    	rt.setId(uuid);
    	
    	for (Device device : devices.getDevice()) {
    		int type = PosType.getByName(device.getPosType()).getValue();
    		PostionReq PostionReq = new PostionReq(device.getID(), type);
    		rt.add(PostionReq);
    	} 
    	logger.info("RequestTask<PostionReq> " + rt);
    	RequestCache.putPostTask(rt);
    }
}
